package main.leetcode.clockin.May;

/**
 * 287.寻找重复数
 *
 * <p>给定一个包含 n + 1 个整数的数组 nums，其数字都在 1 到 n 之间（包括 1 和 n），可知至少存在一个重复的整数。假设只有一个重复的整数，找出这个重复的数。
 *
 * <p>示例 1: 输入: [1,3,4,2,2] 输出: 2
 *
 * <p>示例 2: 输入: [3,1,3,4,2] 输出: 3 说明：
 *
 * <p>不能更改原数组（假设数组是只读的）。 只能使用额外的 O(1) 的空间。 时间复杂度小于 O(n2) 。 数组中只有一个重复的数字，但它可能不止重复出现一次。
 *
 * <p>来源：力扣（LeetCode） 链接：https://leetcode-cn.com/problems/find-the-duplicate-number
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */
public class day26 {
    public static void main(String[] args) {
        System.out.println(new day26().findDuplicate(new int[] {1, 3, 4, 2, 2}));
        System.out.println(new day26().findDuplicate(new int[] {3, 1, 3, 4, 2}));
    }

    public int findDuplicate(int[] nums) {
        int left = 1, right = nums.length - 1;
        int mid, cnt;
        while (left < right) {
            mid = left + (right - left >>> 1);
            cnt = 0;
            for (int num : nums) {
                if (num <= mid) {
                    ++cnt;
                }
            }

            // 比当前中位数小或相等的数的个数占小比例的情况
            if (cnt <= mid) {
                left = mid + 1;
            }
            // 比当前中位数小或相等的数的个数占大比例的情况
            else {
                right = mid;
            }
        }

        return left;
    }
}
